//========================================================================================
//  
//  $File: $
//  
//  Owner: Toan Nguyen
//  
//  $Author: $
//  
//  $DateTime: $
//  
//  $Revision: $
//  
//  $Change: $
//  
//  Copyright 1997-2008 Adobe Systems Incorporated. All rights reserved.
//  
//  NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance 
//  with the terms of the Adobe license agreement accompanying it.  If you have received
//  this file from a source other than Adobe, then your use, modification, or 
//  distribution of it requires the prior written permission of Adobe.
//  
//========================================================================================
#include "VCPlugInHeaders.h"

// Interface includes:
#include "ISubject.h"
#include "ITreeViewMgr.h"
#include "ITreeViewController.h"
#include "ISysFileData.h"
#include "IWidgetParent.h"
#include "ITextControlData.h"
#include "AMPluginDataModel.h"
#include "IApplication.h"
#include "IDialogMgr.h"
#include "IDialog.h"

// General includes:
#include "CDialogObserver.h"
#include "AMPCAlert.h"
#include "AMPIssuesFileNodeID.h"
#include "CObserver.h"
#include "K2Vector.tpp" // For NodeIDList to compile
#include "StreamUtil.h"

// Project includes:
#include "AMPID.h"
#include <stdio.h>
#include <curl/curl.h>
#include "SDKFileHelper.h"
#include "AMGlobal.h"
#include <string.h>
#include "HTTPRequestHelper.h"
//#include <pthread.h>
#include "AMPLogDataRecord.h"
//#include "DelegationPattern.h"
//#include "Notifier.h"
#include "JSONHelper.h"
#include "ITriStateControlData.h"
#include "IDialogController.h"
/// Add check box
#include "IBooleanControlData.h"
#include "IUIFontSpec.h"
#include "CTreeViewWidgetMgr.h"
#include "AMPLogCenter.h"
#include "SDKLayoutHelper.h"

IControlView* iconViewtmpChose;


int addedNotification = 0;

/**	Implements IObserver based on the partial implementation CDialogObserver; 
	allows dynamic processing of dialog widget changes, in this case
	the dialog's info button. 
  
	
	 @ingroup basicdialog
	
*/
class AMPIssuesDlgObserver : public CDialogObserver//, ISubscriber<AMPIssuesDlgObserver>
{
	public:
		//pthread_t		threads;
		/**
			Constructor.
			@param boss interface ptr from boss object on which this interface is aggregated.
		*/
		
		AMPIssuesDlgObserver(IPMUnknown* boss) : CDialogObserver(boss) {
		/*	do {
				string SetDefaultPath =  g_ImagePreview;
				this->doPreview(SetDefaultPath.c_str());
				// get checkout button
				InterfacePtr<IWidgetParent> 
				iWidgetParent(this, UseDefaultIID());
				ASSERT(iWidgetParent);
				if(!iWidgetParent)
				{
					break;
				}
				InterfacePtr<IPanelControlData>	iPanelControlData( 
															  (IPanelControlData*)iWidgetParent->QueryParentFor(IID_IPANELCONTROLDATA) );
			
				ASSERT(iPanelControlData);
				if(!iPanelControlData)
				{
					break;
				}
			
				IControlView* iWidgetView = 
				iPanelControlData->FindWidget(kAMPCheckOutButtonWidgetID);
				ASSERT(iWidgetView);
				if(!iWidgetView) {
					break;
				}

				// Get Next and Previous buttons
				IControlView* nextButtonView = 
				iPanelControlData->FindWidget(kPreviewImageNextWidgetID);
				ASSERT(nextButtonView);
				if(!nextButtonView) {
					break;
				}
				
				IControlView* prevButtonView = 
				iPanelControlData->FindWidget(kPreviewImagePreviousWidgetID);
				ASSERT(prevButtonView);
				if(!prevButtonView) {
					break;
				}
				
				IControlView* radioButtonPanel = iPanelControlData->FindWidget(kAMPClusterPanelWidgetID);
				ASSERT(radioButtonPanel);
				if(!radioButtonPanel)
				{
					break;
				}
				
				if(g_CurPreviewNodeName != "")
				{
					iWidgetView->Enable(kTrue, kTrue);
					nextButtonView->Enable(kTrue);
					prevButtonView->Enable(kTrue);
					radioButtonPanel->Enable(kTrue, kTrue);
				}else
				{
					iWidgetView->Disable(kTrue);
					nextButtonView->Disable(kTrue);
					prevButtonView->Disable(kTrue);
					radioButtonPanel->Disable(kTrue);
				}
				
				
				////cout << "Init thread" << endl;
				// <-- Toan add here to selected radio low images resolution
				InterfacePtr<IPanelControlData> panelControl(iWidgetParent->GetParent(),UseDefaultIID());
				if(!panelControl)
				{
					break;
				}
				IControlView* clusterView = panelControl->FindWidget(kAMPClusterPanelWidgetID);
				if (!clusterView)
				{
					break;
				}
				InterfacePtr<IPanelControlData> clusterPanel(clusterView, UseDefaultIID());
				if (!clusterPanel)
				{
					break;
				}
				IControlView* childView = clusterPanel->FindWidget(kBscRadioLowResWidgetID);
				if (childView == nil)
				{
					break;
				}
				
				InterfacePtr<ITriStateControlData> triData(childView, UseDefaultIID());
				if (triData)
				{
					triData->SetState(ITriStateControlData::kSelected, nil, nil);
				}
				g_Resolution = "low";
				//-->
				//curImgPos = 0;
				//curNodeImgPath = "";
				//curNodeName = "";
			}while (kFalse);
		 */
			this->handleInitIssue();
		}

		/** Destructor. */
		virtual ~AMPIssuesDlgObserver() {
			////cout << "free dialog" << endl;
		}

		/** 
			Called by the application to allow the observer to attach to the subjects 
			to be observed, in this case the dialog's info button widget. If you want 
			to observe other widgets on the dialog you could add them here. 
		*/
		virtual void AutoAttach();

		/** Called by the application to allow the observer to detach from the subjects being observed. */
		virtual void AutoDetach();

		/**
			Called by the host when the observed object changes, in this case when
			the dialog's info button is clicked.
			@param theChange specifies the class ID of the change to the subject. Frequently this is a command ID.
			@param theSubject points to the ISubject interface for the subject that has changed.
			@param protocol specifies the ID of the changed interface on the subject boss.
			@param changedBy points to additional data about the change. 
				Often this pointer indicates the class ID of the command that has caused the change.
		*/
		virtual void Update
		(
			const ClassID& theChange, 
			ISubject* theSubject, 
			const PMIID& protocol, 
			void* changedBy
		);

	void refreshTreeView();
	
	/**	Called by the idle task manager in the app core when the task is running
	 @param appFlags [IN] specifies set of flags which task can check to see if it should do something
	 this time round
	 @param timeCheck [IN] specifies how many milliseconds before the next active task becomes overdue.
	 @return uint32 giving the interval (msec) that should elapse before calling this back
	 */
protected:
	
	/**	Handles a change in the selection when the end user 
	 either clicks on a node or clicks off it
	 */
	void handleSelectionChanged();
	
	string handleDialogCheck(PMString currentPath, PMString imagePath, int DataType, string pNodename);
	
	/**	Sets the path on the preview widget and invalidates it
	 @param path [IN] specifies the path to the asset in 
	 the local file system
	 */
	void doPreview(const PMString& path);
	
	/**	Populates the tree model. 
	*/
	void initTree();
	
	// close dialog 
	void DoCloseDialog(int32 nTypeDialog);
	
	// check out function
	int DlgCheckOutFromCMS(const string &url, string &errorStr);
	
	// write data
	static int write_response(void *ptr, size_t size, size_t nmemb, void *data);

	// analysic story id
	//PMString AnalysicStoryID();
private:

	static void *WaitCallback(void *pParam);
	
	void realtimeUpdate();

	//bool LButtonDownClick();

	void displayImage(int action);
	
	void handleInitIssue();
	
	void getIssueListContent();
	
	//void calcNextIconRsrcID();
public:  
	//void SubscribeAll(INotifier* notifier) { Subscribe(notifier, &AMPIssuesDlgObserver::ma); Subscribe(notifier, &AMPIssuesDlgObserver::mb);};  
	//void UnsubscribeAll(INotifier* notifier) { Unsubscribe(notifier, &AMPIssuesDlgObserver::ma); Unsubscribe(notifier, &AMPIssuesDlgObserver::mb);};  
	//void UnsubscribeSecond(INotifier* notifier) { Unsubscribe(notifier, &AMPIssuesDlgObserver::mb);};  
	//void SubscribeFirst(INotifier* notifier) { Subscribe(notifier, &AMPIssuesDlgObserver::ma);};  
	//void SubscribeIdleTask(INotifier* notifier) { Subscribe(notifier, &AMPIssuesDlgObserver::refreshTreeView); }
	//void UnsubscribeIdleTask(INotifier* notifier) { Unsubscribe(notifier, &AMPIssuesDlgObserver::refreshTreeView);} 
	//void SubscribeNextButton(INotifier* notifier) { Subscribe(notifier, &AMPIssuesDlgObserver::displayNextImage); }
	//void SubscribePrevButton(INotifier* notifier) { Subscribe(notifier, &AMPIssuesDlgObserver::displayPrevImage); }
	//void UnsubscribeNextButton(INotifier* notifier) { Unsubscribe(notifier, &AMPIssuesDlgObserver::displayNextImage); }
	//void UnsubscribePrevButton(INotifier* notifier) { Unsubscribe(notifier, &AMPIssuesDlgObserver::displayPrevImage); } 
//	void SubscribeImageControlButton(INotifier* notifier) { Subscribe(notifier, &AMPIssuesDlgObserver::displayImage); }
//	void UnsubscribeImageControlButton(INotifier* notifier) { Subscribe(notifier, &AMPIssuesDlgObserver::displayImage); }
	
};

/* CREATE_PMINTERFACE
 Binds the C++ implementation class onto its 
 ImplementationID making the C++ code callable by the 
 application.
*/
CREATE_PMINTERFACE(AMPIssuesDlgObserver, kAMPIssuesDlgObserverImpl)
/* AutoAttach
*/
void AMPIssuesDlgObserver::AutoAttach()
{
	initTree();
	// Call the base class AutoAttach() function so that default behavior
	// will still occur (OK and Cancel buttons, etc.).
	CDialogObserver::AutoAttach();

	do
	{
		InterfacePtr<ISubject> mySubj(this, UseDefaultIID()); 
		ASSERT(mySubj);
		mySubj->AttachObserver(this, IID_ITREEVIEWCONTROLLER);
		
		// Get the IPanelControlData interface for the dialog:
		InterfacePtr<IPanelControlData> panelControlData(this, UseDefaultIID());
		if (panelControlData == nil)
		{
			ASSERT_FAIL("AMPIssuesDlgObserver::AutoAttach() panelControlData invalid");
			break;
		}
		
		// Now attach to BasicDialog's info button widget.
		AttachToWidget(kAMPCheckOutButtonWidgetID, IID_IBOOLEANCONTROLDATA, panelControlData);

		// Attach to other widgets you want to handle dynamically here.
		AttachToWidget(kAMPRefreshButtonWidgetID, IID_IBOOLEANCONTROLDATA, panelControlData);
		
		AttachToWidget(kAMPExitIssueButtonWidgetID, IID_IBOOLEANCONTROLDATA, panelControlData);
		
		AttachToWidget(kBscRadioHighResWidgetID, IID_ITRISTATECONTROLDATA, panelControlData);
		
		AttachToWidget(kBscRadioLowResWidgetID, IID_ITRISTATECONTROLDATA, panelControlData);

		//AttachToWidget(kAMPCheckboxPageWidgetId, IID_IBOOLEANCONTROLDATA, panelControlData);
		// Add Notification
		////cout << "add notification - testNum:" << endl;
		if (addedNotification < 1) {
			//SubscribeIdleTask(Notifier::GetInstance());  	
			//SubscribeNextButton(Notifier::GetInstance());
			//SubscribePrevButton(Notifier::GetInstance());
//			SubscribeImageControlButton(Notifier::GetInstance());
//			addedNotification++;
		}
	} while (false);
}

/* AutoDetach
*/
void AMPIssuesDlgObserver::AutoDetach()
{
	// Call base class AutoDetach() so that default behavior will occur (OK and Cancel buttons, etc.).
	CDialogObserver::AutoDetach();

	do
	{
		InterfacePtr<ISubject> mySubj(this, UseDefaultIID()); 
		ASSERT(mySubj);
		mySubj->DetachObserver(this, IID_ITREEVIEWCONTROLLER);
		// Get the IPanelControlData interface for the dialog:
		InterfacePtr<IPanelControlData> panelControlData(this, UseDefaultIID());
		if (panelControlData == nil)
		{
			ASSERT_FAIL("AMPIssuesDlgObserver::AutoDetach() panelControlData invalid");
			break;
		}
		
		// Now we detach from BasicDialog's info button widget.
		DetachFromWidget(kAMPCheckOutButtonWidgetID, IID_IBOOLEANCONTROLDATA, panelControlData);

		// Detach from other widgets you handle dynamically here.
		DetachFromWidget(kAMPRefreshButtonWidgetID, IID_IBOOLEANCONTROLDATA, panelControlData);
		
		DetachFromWidget(kAMPExitIssueButtonWidgetID, IID_IBOOLEANCONTROLDATA, panelControlData);
		
		DetachFromWidget(kBscRadioHighResWidgetID, IID_ITRISTATECONTROLDATA, panelControlData);
		
		DetachFromWidget(kBscRadioLowResWidgetID, IID_ITRISTATECONTROLDATA, panelControlData);
		
		//DetachFromWidget(kAMPCheckboxPageWidgetId, IID_IBOOLEANCONTROLDATA, panelControlData);
		// Remove notification
		//UnsubscribeIdleTask(Notifier::GetInstance());
		//UnsubscribeNextButton(Notifier::GetInstance());
		//UnsubscribePrevButton(Notifier::GetInstance());
//		UnsubscribeImageControlButton(Notifier::GetInstance());
//		addedNotification--;
		
	} while (false);
}

/* Update
*/
void AMPIssuesDlgObserver::Update
(
	const ClassID& theChange, 
	ISubject* theSubject, 
	const PMIID &protocol, 
	void* changedBy
)
{
	// Call the base class Update function so that default behavior will still occur (OK and Cancel buttons, etc.).
	CDialogObserver::Update(theChange, theSubject, protocol, changedBy);
	////cout << "AMPIssuesDlgObserver::Update" << endl;
	do
	{
		InterfacePtr<IControlView> controlView(theSubject, UseDefaultIID());
		if (controlView == nil)
		{
			ASSERT_FAIL("AMPIssuesDlgObserver::Update() controlView invalid");
			break;
		}
		////cout << "AMPIssuesDlgObserver::Update" << endl;
		// Get the button ID from the view.
		WidgetID theSelectedWidget = controlView->GetWidgetID();

		switch(theChange.Get())
		{
			case kListSelectionChangedMessage:
			{
				////cout << "kListSelectionChangedMessage" << endl;
				this->handleSelectionChanged();
				break;
			}
				
			default:
			{
				ASSERT_FAIL (FORMAT_ARGS ("AMPIssuesDlgObserver::Update does not support theChange (%x)", theChange.Get()));
				break;
			}
		}

		if (theSelectedWidget == kAMPCheckOutButtonWidgetID && theChange == kTrueStateMessage)
		{  
			if((g_Issueid == "")||(g_pageNumberCheckOut == ""))
			{
				InterfacePtr<IPanelControlData> panelControlData(this, UseDefaultIID());
				if (panelControlData == nil)
				{
					break;
				}
				IControlView* iWidgetView = panelControlData->FindWidget(kAMPCheckOutButtonWidgetID);
				ASSERT(iWidgetView);
				if(!iWidgetView) {
					break;
				}
				iWidgetView->Disable(kTrue);
				break;
			}
			//if (g_DocName.length() > 0 && g_IsCheckOut == TRUE) { // there is checked out story 
			//if (g_DocName.length() > 0 && AMPUtils::FrontDocName().length() > 0) { // there is checked out story
			if (g_DocName.length() > 0 && AMPUtils::FindFrontDocsName(g_DocName.c_str()) == TRUE) { // there is page need to checked in

				AMPCAlert::ModalAlert
				(
				 //kBscDlgLoginFailStringKey,		// Alert string
				 PMString("\nPlease check-in or discard open files before you check-out a new one."),		// Alert string
				 "OK",
				 kNullString, 					// No second button
				 kNullString, 					// No third button
				 kNoNeedToWaitForDialog,		// Set OK button to default
				 1								// No icon.
				 );
				break;
			}
checkout_package:			
			string api_prefix = API_PREFIX;
			string urlStory = g_Domain + "/" + api_prefix + "/pages/" + g_Issueid + "/" + g_Storyid;
#if _INDESIG_DEBUG
			////cout << "urlStory: " << urlStory << endl;
#endif
			string error;
			//g_IsCheckOut = DlgCheckOutFromCMS(urlStory, error);
			int checkoutRes = DlgCheckOutFromCMS(urlStory, error);
			if (checkoutRes == FALSE)
			{
				////cout << "error: " << error << endl;
				if(error == PackageLocked || error == PagesLocked)
				{
					int16 result = AMPCAlert::ModalAlert
					(
					 PMString("\n\nContent locked. Unlock it and check-out again?"),		// Alert string
					 PMString("Yes"),						// YES button
					 PMString("No"),						// NO button
					 PMString("Unlock"),					// Unlock button
					 kNeedToWaitForDialog,										// Set OK button to default
					 1										// No icon.
					 );
					if(result == kOKSystem)
					{
						////cout << "unlock and check out package" << endl;
						bool unlock = HTTPRequestHelper::UnlockPackagetoCheckOut(error);
						if(unlock == TRUE)
							goto checkout_package;
						else
							goto error_checkout;
					}
					else if(result == kUnlockSystem)
					{
						////cout << "unlock package" << endl;
						bool unlock = HTTPRequestHelper::UnlockPackagetoCheckOut(error);
						if(unlock == FALSE) {
							goto error_checkout;
						}else {
							// refesh issue list
							getIssueListContent();
						}
					}
				} else
				{
error_checkout:
					// About box
					PMString _errorCode = PMString(error.c_str());		// Alert string
					AMPCAlert::ModalAlert
					(
						_errorCode,//PMString(error.c_str()),
						"OK",
						kNullString, 					// No second button
						kNullString, 					// No third button
						kNoNeedToWaitForDialog,			// Set OK button to default
						1								// No icon.
					 );
				}
				
			}else if(checkoutRes == AMCannotOpen)
			{
				AMPUtils::ResetLogFile();
				//AMPUtils::ClearPackageAndSessionInfo();
				//AMPUtils::RefreshMainPanel(FALSE);
				//cout << "refresh main panel after checking out" << endl;
				break;
			}else if(checkoutRes != AMUnknown)
			{
				DoCloseDialog(1);
				AMPUtils::RefreshMainPanel(kAMPLuginCheckoutActionID);
				////cout << "refresh main panel after checking out" << endl;
				//ResetGlobalValue();
				//SaveLogHeaderFile();
			//	string sessionID = LoadSessionInfo();
			//	if (sessionID.length() == 0) {
			//		SaveSessionInfo();
			//	}
				SaveSessionInfo();
			}
			//g_IsIssueEnable = FALSE;
		}
		
		if (theSelectedWidget == kAMPRefreshButtonWidgetID && theChange == kTrueStateMessage)
		{
			// refesh issue list
			getIssueListContent();
			/*
			RangeProgressBar * RefreshProg;
			//RangeProgressBar * FillProgress;
			RefreshProg = new RangeProgressBar("Downloading...", 0, 200, kTrue, kFalse, nil, kFalse);
			string api_prefix = API_PREFIX;
			RefreshProg->SetPosition(5);
			string content = HTTPRequestHelper::getDataFromURL(g_Domain + "/" + api_prefix+"/magazines");
			RefreshProg->SetPosition(55);
			int fraction = 120;
			if(g_Magazine_Count > 0) {
				fraction = fraction / g_Magazine_Count;
			}
			JSONHelper::initMagazines(content);
			for (int i = 0; i < g_Magazine_Count; i++) {
				//string issueURL = g_Domain + "/" + api_prefix + "/magazines_revise/" + g_Magazines[i]._id;
				string issueURL = g_Domain + "/" + api_prefix + "/magazines/" + g_Magazines[i]._id;
				string issueContent = HTTPRequestHelper::getDataFromURL(issueURL);
				JSONHelper::fillMagazine(i, issueContent, FALSE, 60 + i*fraction, 60 + (i+1)*fraction, RefreshProg, TRUE);
			}
			for (int j = 0; j < g_Magazine_Count; j++) {
				if (g_Magazines[j]._issueSize > 0) {
					refreshTreeView();
					RefreshProg->SetPosition(180+j);
					break;
				}
			}
			//refreshTreeView();
			//DoCloseDialog(1);
			RefreshProg->~RangeProgressBar();
			 */
		}
		if (theSelectedWidget == kAMPExitIssueButtonWidgetID && theChange == kTrueStateMessage) {
			////cout << "Call Refresh button" << endl;
			// return all param selected before
			LoadSessionInfo(); // load data from session info file
			//ReFreshTreeView();
			DoCloseDialog(1);
			//g_IsIssueEnable = FALSE;
		}
	
		if (theSelectedWidget == kBscRadioHighResWidgetID && theChange == kTrueStateMessage)
		{
			////cout << "select hight resolution" << endl;
			g_Resolution = "high";
			// test display two image preview
		}
		
		if (theSelectedWidget == kBscRadioLowResWidgetID && theChange == kTrueStateMessage)
		{
			////cout << "select low resolution" << endl;
			g_Resolution = "low";
			// test display two image preview
		}
	
	} while (false);
	
}



/********************************************************************************************************************
 *****Function: initTree
 *****Creator:  Toan Nguyen
 *****IN: 
 *****out:
 *****Objective: init tree view
 ********************************************************************************************************************/
void AMPIssuesDlgObserver::initTree()
{
	do
	{
		//printf("init Tree \n");
		InterfacePtr<AMPluginDataModel> model(this, UseDefaultIID());
		ASSERT(model);
		if(!model) {
			break;
		}
		// Get latest folder from option
		//PMString folderRootPath = PnlTrvUtils::GetFolderSelectedPath();	//xxxx
		PMString RootPath("Browse Issues");
		// Empty folder path is fine, for instance, if we undid setting
		// the path when we just started up, it should be OK to do this
		//model->Rebuild(folderRootPath);
		model->Rebuild(RootPath);
		InterfacePtr<ITreeViewMgr>	
			treeViewMgr(this, UseDefaultIID());
		ASSERT(treeViewMgr);
		if(treeViewMgr == nil)
		{
			//printf("treeViewMgr == nil \n");
			break;
		}
		treeViewMgr->ClearTree();
		treeViewMgr->ChangeRoot(kTrue);
	} while(kFalse);
	
	//curImgPos = 0;
	//g_CurPreviewImgPos = 0;
	//curNodeImgPath = "";
	//curNodeName = "";
}

/********************************************************************************************************************
 *****Function: DoCloseDialog
 *****Creator:  Toan Nguyen
 *****IN: int32 nTypeDialog
 *****out: int
 *****Objective: close dialog
 ********************************************************************************************************************/
void AMPIssuesDlgObserver::DoCloseDialog(int32 nTypeDialog)
{
	do
	{
		// Get the application interface and the DialogMgr.
		InterfacePtr<IApplication> application(GetExecutionContextSession()->QueryApplication());
		if (application == nil)
		{
			ASSERT_FAIL("AMPIssuesDlgObserver::DoDialog: application invalid");
			break;
		}
		InterfacePtr<IDialogMgr> dialogMgr(application, UseDefaultIID());
		if (dialogMgr == nil)
		{ 
			ASSERT_FAIL("AMPIssuesDlgObserver::DoDialog: dialogMgr invalid"); 
			break;
		}
		
		InterfacePtr<IWidgetParent> iWidgetParent(this, UseDefaultIID());
		if(!iWidgetParent)
			break;
		
		InterfacePtr<IDialog> iDialog((IDialog *) iWidgetParent->QueryParentFor(IID_IDIALOG));
		iDialog->Close();
	} while (false);
}

int AMPIssuesDlgObserver::write_response(void *ptr, size_t size, size_t nmemb, void *data)
{
	FILE *writehere = (FILE *)data;
	return fwrite(ptr, size, nmemb, writehere);
}

/********************************************************************************************************************
 *****Function: DlgCheckOutFromCMS
 *****Creator:  Toan Nguyen
 *****IN: const string &url, string &errorStr
 *****out: int
 *****Objective: check out pages
 ********************************************************************************************************************/
int AMPIssuesDlgObserver::DlgCheckOutFromCMS(const string &url, string &errorStr)
{
	string _error_info;
	CURL *curl_download;
	CURLcode res;
	FILE *ftpfile;
	string urlRoot;
	struct myprogress prog;
	string fileIDML;
	string requestError;
	string timeup;
	//ResetGlobalValue();
	SaveLogHeaderFile();
	string deleteLink = "cd " + g_System_WorkspaceDir + " && rm -rf Links";
	system(deleteLink.c_str());
	
	// workspace has been created when plug-in loaded
	string tmpPath = g_System_WorkspaceDir;
	string PathDownload(tmpPath.c_str());
	PathDownload += "\\AMPInDesign.zip";
	//username and password 
	urlRoot = HTTPRequestHelper::getPackageURL(url, requestError);
	RangeProgressBar *progressbar;
	progressbar = new RangeProgressBar("Checking out...", 0, 200, kTrue, kFalse, nil, kFalse);
	progressbar->SetPosition(5);
	if (urlRoot == string("") || urlRoot == "LOCKED")
	{
		//cout << "requestError: " << requestError << endl;
		if(urlRoot == "LOCKED")
		{
			errorStr = PagesLocked;
		}else
		{
			errorStr = requestError;
		}
		_error_info = "Failed to checking out package from server";
		SaveLogCenterData(_error_info);
		AMPLogCenter::DataLogCenter(AMPPLUGIN_CHECKOUT_FAILED);
		
		progressbar->~RangeProgressBar();
		delete progressbar;
		//errorStr = "Audience Media InDesign Plug-in\n\nPackage is already existed on the CMS";
		return FALSE;
	}
	g_IDMLzip = AMPUtils::getNameFromURL(urlRoot);
	progressbar->SetPosition(10);
	fileIDML = g_Package_id + ".idml";

retry_checkout:
	/*
	int32 resss = HTTPRequestHelper::DownloadZipfile(urlRoot);
	if (resss == -1) {
		int16 result = AMPCAlert::ModalAlert
			(
				PMString("\nInternet connection lost.\n\nRetry check-out of the package?"),		// Alert string
				PMString("Yes"),				// OK button
				PMString("No"), 				// No button
				kNullString, 					// No third button
				kNeedToWaitForDialog,								// Set OK button to default
				1								// No icon.
			 );
			if (result == kOKSystem)
			{
				//deleteLink = "cd " + g_System_WorkspaceDir + " && rm -rf AMPInDesign.zip AMPbackupInDesign.zip";
				//system(deleteLink.c_str());
				goto retry_checkout;
			}else{
				//cout << "checkout curl_easy_perform: " << res << endl;
				errorStr = "Failed to check out IDML file";
				//unlock package check out
				HTTPRequestHelper::UnlockPackagetoCheckOut(errorStr);
				return AMUnknown;
			}
	}
	*/
	progressbar->SetTaskText("Checking out...", TRUE);
	// local file name to store the file as
	ftpfile = fopen(PathDownload.c_str(), "wb");
	AMPUtils::CalculateTimer(TRUE);
	curl_download = curl_easy_init();
	if(curl_download) {
		prog.lastruntime = 0;
		prog.curl = curl_download;
		prog.MinPos = 15;
		prog.MaxPos = 180;
		prog.DownUp = DOWNLOADCOMMAND;
		prog.Progress = progressbar;
		HTTPRequestHelper::setProxyServer(curl_download);
		// Get a file listing from sunet
		curl_easy_setopt(curl_download, CURLOPT_URL, urlRoot.c_str());
		//progressbar->SetPosition(35);
		curl_easy_setopt(curl_download, CURLOPT_USERPWD, g_Authentication);
		curl_easy_setopt(curl_download, CURLOPT_WRITEFUNCTION, write_response);
		curl_easy_setopt(curl_download, CURLOPT_WRITEDATA, ftpfile);
		// progress function 
		curl_easy_setopt(curl_download, CURLOPT_PROGRESSFUNCTION, HTTPRequestHelper::progress);
		// pass the struct pointer into the progress function 
		curl_easy_setopt(curl_download, CURLOPT_PROGRESSDATA, &prog);
		curl_easy_setopt(curl_download, CURLOPT_NOPROGRESS, 0L);
		//<-- end of progress fuction
		curl_easy_setopt(curl_download, CURLOPT_CONNECTTIMEOUT, 1000);
		curl_easy_setopt(curl_download, CURLOPT_TIMEOUT, 1000);
		res = curl_easy_perform(curl_download);
		// always cleanup
		curl_easy_cleanup(curl_download);
		timeup = AMPUtils::CalculateTimer(FALSE);
		if(res != CURLE_OK)
		{
			fclose(ftpfile);  //close the local file 
			_error_info = "Failed to checking out package from server, connection lost";
			_error_info = _error_info + "\nCheck-out page Failed. Total time download: " + timeup + "s";
			SaveLogCenterData(_error_info);
			AMPLogCenter::DataLogCenter(AMPPLUGIN_DOWNLOADING_FAILED);
			int16 result = AMPCAlert::ModalAlert
			(
				PMString("\n\nInternet connection lost.\n\nRetry check-out of the package?"),		// Alert string
				PMString("Yes"),				// OK button
				PMString("No"), 				// No button
				kNullString, 					// No third button
				kNeedToWaitForDialog,								// Set OK button to default
				1								// No icon.
			 );
			if (result == kOKSystem)
			{
				//deleteLink = "cd " + g_System_WorkspaceDir + " && rm -rf AMPInDesign.zip AMPbackupInDesign.zip";
				//system(deleteLink.c_str());
				goto retry_checkout;
			}else{
				//cout << "checkout curl_easy_perform: " << res << endl;
				progressbar->SetPosition(200);
				progressbar->~RangeProgressBar();
				errorStr = "Failed to check out IDML file";
				//unlock package check out
				HTTPRequestHelper::UnlockPackagetoCheckOut(errorStr);
				return AMUnknown;
			}
		}
	}
	progressbar->SetTaskText("Please wait...", TRUE);
	fclose(ftpfile); //close the local file

	//string excutePath = "tar -xvf ";
	string excutePath = "cd " + g_System_WorkspaceDir + " && unzip AMPInDesign.zip";
	////cout << "System command: " << excutePath << "\nPath download " << PathDownload << endl;
	int retCode = system(excutePath.c_str());
	if(retCode != 0)
	{
		int16 result = AMPCAlert::ModalAlert
		(
		 PMString("\n\nDownload error. Retry Check-out?"),		// Alert string
		 PMString("Yes"),				// OK button
		 PMString("No"), 				// No button
		 kNullString, 					// No third button
		 kNeedToWaitForDialog,								// Set OK button to default
		 1								// No icon.
		 );
		_error_info = "Download error. Total time download: " + timeup + "s";
		SaveLogCenterData(_error_info);
		AMPLogCenter::DataLogCenter(AMPPLUGIN_DOWNLOADING_FAILED);
		if (result == kOKSystem)
		{
			//deleteLink = "cd " + g_System_WorkspaceDir + " && rm -rf AMPInDesign.zip AMPbackupInDesign.zip";
			//system(deleteLink.c_str());
			goto retry_checkout;
		}else{
			//cout << "+++error curl_easy_perform: " << res << endl;
			progressbar->SetPosition(200);
			progressbar->~RangeProgressBar();
			errorStr = "Audience Media InDesign Plug-in\n\nFailed to check out IDML file";
			//unlock package checked out
			HTTPRequestHelper::UnlockPackagetoCheckOut(errorStr);
			return AMUnknown;
		}
	}
	// open origin idml
	//g_Package_id = "issue_72_page_1_1234567890";		// test_20121210
	UIDRef docRef = UIDRef::gNull;
	ErrorCode _err = kFailure;
	string path = g_SDK_WorkspaceDir + "\\" + fileIDML;
	//string path = "Macintosh HD:Users:toan:Desktop:82cff8bd253a974f726f7e1272fb4a3a.idml"; // test_20121210
	PMString fileLocation(path.c_str());
	IDFile chosenFile(fileLocation);
	SDKLayoutHelper openHelper;
	if(g_assignmentPtr.size() > 0) {
		g_assignmentPtr.clear();
	}
	docRef = openHelper.OpenDocument(chosenFile, K2::kSuppressUI);
	if(docRef != UIDRef::gNull) {
		//cout << "Open layout window" << endl;
		_err = openHelper.OpenLayoutWindow(docRef);
	}
	if(docRef == UIDRef::gNull || _err == kFailure)
	{
		//cout << "cannot Open layout window" << endl;
		deleteLink = "rm -rf " + g_System_WorkspaceDir + "/" + fileIDML;
		retCode = system(deleteLink.c_str());
		int16 result = AMPCAlert::ModalAlert
		(
		 PMString("\n\nFile error. Please contact the Administrator."),		// Alert string
		 PMString("Yes"),				// OK button
		 kNullString,					// No button
		 kNullString, 					// No third button
		 kNeedToWaitForDialog,								// Set OK button to default
		 1								// No icon.
		 );
		
		_error_info = "Couldn't open idml file: " + g_Issueid + " - " + g_pageNumberCheckOut + " - "+ g_Resolution;
		_error_info = _error_info + "\nCheck-out page Failed. Total time download: " + timeup + "s";
		SaveLogCenterData(_error_info);
		AMPLogCenter::DataLogCenter(AMPPLUGIN_COULDNT_IMPORT_IDML);
		progressbar->~RangeProgressBar();
		return AMCannotOpen;
	}
	////cout << "--retCode: " << retCode << endl;
	//ReFreshTreeView();
	///refreshTreeView();
	g_pageEditing = g_pageNumberCheckOut;
	g_issueEditing = g_Issueid;
	SaveLogHeaderFile();
	progressbar->SetPosition(185);
//	deleteLink = "rm -rf " + PathbackDownload;
//	retCode = system(deleteLink.c_str());
	_error_info = "Checked out pages successful.";
	_error_info = _error_info + "Total time download: " + timeup + "s";
	SaveLogCenterData(_error_info);
	progressbar->SetPosition(190);
	path = g_SDK_WorkspaceDir + ":" + g_Package_id + ".indd";
	PMString saveLocation(path.c_str());
	IDFile saveFile(saveLocation);
	openHelper.SaveDocumentAs(docRef, saveFile, K2::kSuppressUI);
	progressbar->SetPosition(195);
	AMPUtils::AddToAssignment();
	if(g_assigneeSt.size() > 0) {
		g_assigneeSt.clear();
	}
	progressbar->~RangeProgressBar();
	return TRUE; 
}

/********************************************************************************************************************
 *****Function: handleSelectionChanged
 *****Creator:  Toan Nguyen
 *****IN: 
 *****out: 
 *****Objective: process selection changed 
 ********************************************************************************************************************/
void AMPIssuesDlgObserver::handleSelectionChanged()
{
	do
	{
		string   StoryID;
		PMString story_id;
		string displayString;
		
		InterfacePtr<ITreeViewController> controller(this, UseDefaultIID());
		ASSERT(controller);
		if(!controller)
		{
			break;
		}
		int GetNodeChosen = NODE_UNSELECTED;
		int TypeNode = ROOT_NODE;
		int selectedItemType = -1;
		NodeIDList selectedItems;
		controller->GetSelectedItems(selectedItems);
		// We've got single selection only
		if(selectedItems.size()>0)
		{
			TreeNodePtr<AMPIssuesFileNodeID> nodeID(selectedItems[0]);
			ASSERT(nodeID);
			if(!nodeID)
			{
				break;
			}
			story_id = nodeID->GetPath();
			////cout << "[0] :" << story_id.GrabCString() << endl;
			PMString pstr(nodeID->GetImgPath());
			PMString pstrNodeName(nodeID->GetDisplayName());
			////cout << "pstr: " << pstr.GrabCString() << endl;
			////cout << "pstrNodeName: " << pstrNodeName.GrabCString() << endl;
			string nodeImgPath = pstr.GrabCString();
			string previewImgPath = nodeImgPath.substr(0, nodeImgPath.find(";")); 
			////cout << "previewImgPath: " << previewImgPath << endl;
			//this->doPreview(previewImgPath.c_str());
			selectedItemType = (nodeID->GetDataType());
			//curNodeImgPath = pstr.GrabCString();
			//curNodeName = pstrNodeName.GrabCString();
			//g_CurPreviewImgPos = 0;
			/*
			if (nodeID->GetDataType() == PAGE_NODE) {
				PMString nodeName(nodeID->GetDisplayName());
				string nodeNameStr = nodeName.GrabCString();
				displayString = nodeNameStr.substr(0, nodeNameStr.find(","));
			}
			else {
				displayString = "Preview";
			}
			*/
			TypeNode = nodeID->GetDataType();
			if(TypeNode == PAGE_NODE) {
				displayString = this->handleDialogCheck(story_id, pstr, nodeID->GetDataType(), pstrNodeName.GrabCString());
			}
		}
		//NodeID node = controller->GetMasterItem();
		controller->Deselect(controller->GetMasterItem());
		// get checkout button
		InterfacePtr<IWidgetParent> 
		iWidgetParent(this, UseDefaultIID());
		ASSERT(iWidgetParent);
		if(!iWidgetParent)
		{
			break;
		}
		InterfacePtr<IPanelControlData>	iPanelControlData( 
														  (IPanelControlData*)iWidgetParent->QueryParentFor(IID_IPANELCONTROLDATA) );
		
		ASSERT(iPanelControlData);
		if(!iPanelControlData)
		{
			break;
		}
		
		IControlView* iWidgetView = 
		iPanelControlData->FindWidget(kAMPCheckOutButtonWidgetID);
		ASSERT(iWidgetView);
		if(!iWidgetView) {
			break;
		}
		
		// Get Next and Previous buttons
		IControlView* nextButtonView = 
		iPanelControlData->FindWidget(kPreviewImageNextWidgetID);
		ASSERT(nextButtonView);
		if(!nextButtonView) {
			break;
		}
		
		IControlView* prevButtonView = 
		iPanelControlData->FindWidget(kPreviewImagePreviousWidgetID);
		ASSERT(prevButtonView);
		if(!prevButtonView) {
			break;
		}
		
		IControlView* textMessageWidget = iPanelControlData->FindWidget(kAMPIssuesTextMessageWidgetID);
		ASSERT(textMessageWidget);
		if(!textMessageWidget)
		{
			break;
		}
		
		InterfacePtr<ITextControlData> 
		textControlData(textMessageWidget, UseDefaultIID());
		ASSERT(textControlData);
		if(!textControlData)
		{
			break;
		}
		if(TypeNode == PAGE_NODE && (displayString != "")) {
			textControlData->SetString(displayString.c_str());
		}
		IControlView* radioButtonPanel = iPanelControlData->FindWidget(kAMPClusterPanelWidgetID);
		ASSERT(radioButtonPanel);
		if(!radioButtonPanel)
		{
			break;
		}
		
		if(g_pageNumberCheckOut != "")
		{
			iWidgetView->Enable(kTrue, kTrue);
			
			//textMessageWidget->Enable(kTrue, kTrue);
			radioButtonPanel->Enable(kTrue, kTrue);
		}else
		{
			// disable it in other cases
			iWidgetView->Disable(kTrue);
			//textMessageWidget->Disable(kTrue);
			radioButtonPanel->Disable(kTrue);
		}
		
		if((TypeNode == PAGE_NODE) && (displayString != ""))
		{
			
			displayString = displayString + ",";
			string tmpNodeName = g_CurPreviewNodeName.substr(g_CurPreviewNodeName.find(",") + 1);
			////cout << displayString << " - " << g_CurPreviewNodeName << " - " << tmpNodeName << endl;
			if((displayString == g_CurPreviewNodeName))	// only select one page
			{
				nextButtonView->Disable(kTrue);
				prevButtonView->Disable(kTrue);
			}else if(tmpNodeName.find(displayString) == (tmpNodeName.length() - displayString.length()))	// selected page at last node name
			{
				prevButtonView->Enable(kTrue, kTrue);
				nextButtonView->Disable(kTrue);
			}else if(tmpNodeName.find(displayString) != string::npos)	// selected page at second node name
			{
				nextButtonView->Enable(kTrue, kTrue);
				prevButtonView->Enable(kTrue, kTrue);
			}else if((tmpNodeName.find(displayString) == string::npos) && (g_CurPreviewNodeName.find(displayString) != string::npos))	// selected page at first node name
			{
				nextButtonView->Enable(kTrue, kTrue);
				prevButtonView->Disable(kTrue);
			}
			g_CurPreviewImgPos = 0;
			int current_find = g_CurPreviewNodeName.find(displayString);
			char *ss = ",";
			int run;
			for(run = 0; run < current_find; run++)
			{
				if(g_CurPreviewNodeName.at(run) == ss[0])
				{
					g_CurPreviewImgPos++;
				}
			}
			////cout << "g_CurPreviewImgPos: " << g_CurPreviewImgPos << endl;
		}
		/*
		if (selectedItemType == PAGE_NODE) {
			prevButtonView->Disable(kTrue);
			string tmp = curNodeImgPath.substr(curNodeImgPath.find(";") + 1);
			if (tmp.length() > 0) {
				nextButtonView->Enable(kTrue, kTrue);
			}
			else {
				nextButtonView->Disable(kTrue);
			}
			//iWidgetView->Disable(kTrue);
			iWidgetView->Enable(kTrue, kTrue);

			//textMessageWidget->Enable(kTrue, kTrue);
			//radioButtonPanel->Disable(kTrue);
			radioButtonPanel->Enable(kTrue, kTrue);
		}
		else if (selectedItemType == STORY_NODE) {
			// enable check out button if selected item is story
			//g_Storyid = "";
			StoryID = story_id.GrabCString();
			AMPUtils::getid(StoryID);
			//g_Storyid = AMPUtils::getNameFromURL(StoryID);
			iWidgetView->Enable(kTrue, kTrue);
			nextButtonView->Disable(kTrue);
			prevButtonView->Disable(kTrue);			
			//textMessageWidget->Disable(kTrue);
			radioButtonPanel->Enable(kTrue, kTrue);
		}
		else {
			// disable it in other cases
			iWidgetView->Disable(kTrue);
			nextButtonView->Disable(kTrue);
			prevButtonView->Disable(kTrue);
			//textMessageWidget->Disable(kTrue);
			radioButtonPanel->Disable(kTrue);
		}
		 */
		
	} while(kFalse);
}


/********************************************************************************************************************
 *****Function: doPreview
 *****Creator:  Toan Nguyen
 *****IN: const PMString& path
 *****out: 
 *****Objective: set image preview path 
 ********************************************************************************************************************/
void AMPIssuesDlgObserver::doPreview(const PMString& path)
{
	
	do
	{
		////cout << "doPreview path: " << path.GrabCString() << endl;
		//PMString imgPath("Macintosh HD:Users:vutiet:AMPInDesignPlugin:Grazia.jpg");
		//SDKFileHelper fileHelper(imgPath);
//		SDKFileHelper fileHelper(path);
//		IDFile xFile = fileHelper.GetIDFile();
		string DetectPath = path.GrabCString();
		bool b_kTwoImagePreview = TRUE;
		if(DetectPath.find("||||") != string::npos)
		{
			b_kTwoImagePreview = FALSE;
		}
		
		InterfacePtr<IWidgetParent> 
		iWidgetParent(this, UseDefaultIID());
		ASSERT(iWidgetParent);
		if(!iWidgetParent)
		{
			//cout << "iWidgetParent is nil" << endl;  
			break;
		}
		InterfacePtr<IPanelControlData>	iPanelControlData( 
														  (IPanelControlData*)iWidgetParent->QueryParentFor(IID_IPANELCONTROLDATA) );
		
		ASSERT(iPanelControlData);
		if(!iPanelControlData)
		{
			//cout << "iPanelControlData is nil" << endl;  
			break;
		}
		
		IControlView* iPreviewMainView = iPanelControlData->FindWidget(kAMPGroupViewPanelWidgetID);
		ASSERT(iPreviewMainView);
		if(!iPreviewMainView) {
			break;
		}
		
		IControlView* iLeftRightView = iPanelControlData->FindWidget(kAMPGroupPanelWidgetID);
		ASSERT(iLeftRightView);
		if(!iLeftRightView) {
			break;
		}
		
		IControlView* iWidgetView = 
		iPanelControlData->FindWidget(kAMPCustomPanelViewWidgetID);
		ASSERT(iWidgetView);
		if(!iWidgetView) {
			////cout << "iWidgetView is nil" << endl;  
			break;
		}
		
		IControlView* iLeftPreviewWidgetView = 
		iPanelControlData->FindWidget(kAMPLeftPanelViewWidgetID);
		ASSERT(iLeftPreviewWidgetView);
		if(!iLeftPreviewWidgetView) {
			////cout << "iWidgetView is nil" << endl;  
			break;
		}
		
		IControlView* iRightPreviewWidgetView = 
		iPanelControlData->FindWidget(kAMPRightPanelViewWidgetID);
		ASSERT(iRightPreviewWidgetView);
		if(!iRightPreviewWidgetView) {
			////cout << "iWidgetView is nil" << endl;  
			break;
		}
		
		////cout << "b_kTwoImagePreview: " << b_kTwoImagePreview << endl;
		if(b_kTwoImagePreview) {
			
			// display page preview at center
			iLeftRightView->Disable();
			iLeftRightView->Hide();
			iLeftPreviewWidgetView->Disable();
			iLeftPreviewWidgetView->Hide();
			iRightPreviewWidgetView->Disable();
			iRightPreviewWidgetView->Hide();
			
			iPreviewMainView->Enable(TRUE, TRUE);
			iPreviewMainView->Show();
			iWidgetView->Enable(TRUE, TRUE);
			iWidgetView->Show();
			
			SDKFileHelper fileHelper(path);
			IDFile xFile = fileHelper.GetIDFile();
			
			// below, if we could find the stream, we'll set this true
			InterfacePtr<IPMStream> 
			iDataFileStream(StreamUtil::CreateFileStreamReadLazy(xFile));
			// If nil, we couldn't have opened this
			if (iDataFileStream == nil)
			{
				////cout << "iDataFileStream is nil" << endl;  
				break;
			}
			
			iDataFileStream->Close();
			
			InterfacePtr<ISysFileData> 
			iSysFileData(iWidgetView, IID_ISYSFILEDATA);
			ASSERT(iSysFileData);
			if(!iSysFileData)
			{
				//cout << "iSysFileData is nil" << endl;  
				break;
			}
			iSysFileData->Set(xFile);
			
			iWidgetView->Invalidate();
			
		}else{
			// display page preview at left and right side
			iPreviewMainView->Disable(TRUE);
			iPreviewMainView->Hide();
			iWidgetView->Disable(TRUE);
			iWidgetView->Hide();
			
			iLeftRightView->Enable(TRUE, TRUE);
			iLeftRightView->Show();
			iLeftPreviewWidgetView->Enable(TRUE, TRUE);
			iLeftPreviewWidgetView->Show();
			iRightPreviewWidgetView->Enable(TRUE, TRUE);
			iRightPreviewWidgetView->Show();
			
			string tmpPath = path.GrabCString();
			string leftpath, rightpath;
			leftpath = tmpPath.substr(0, tmpPath.find("||||"));
			rightpath = tmpPath.substr(tmpPath.find("||||")+4, tmpPath.length());
			
			// display left preview
			
			SDKFileHelper leftfileHelper(leftpath.c_str());
			IDFile xLeftFile = leftfileHelper.GetIDFile();
			
			// below, if we could find the stream, we'll set this true
			InterfacePtr<IPMStream> 
			iLeftPreviewDataFileStream(StreamUtil::CreateFileStreamReadLazy(xLeftFile));
			// If nil, we couldn't have opened this
			if (iLeftPreviewDataFileStream == nil)
			{
				////cout << "iDataFileStream is nil" << endl;  
				break;
			}
			
			iLeftPreviewDataFileStream->Close();
			
			InterfacePtr<ISysFileData> 
			iLeftPreviewSysFileData(iLeftPreviewWidgetView, IID_ISYSFILEDATA);
			ASSERT(iLeftPreviewSysFileData);
			if(!iLeftPreviewSysFileData)
			{
				//cout << "iSysFileData is nil" << endl;  
				break;
			}
			iLeftPreviewSysFileData->Set(xLeftFile);
			
			iLeftPreviewWidgetView->Invalidate();
			
			//+++++++++++++++++++++++++++++++++++++//
			// display right preview
			
			SDKFileHelper rightfileHelper(rightpath.c_str());
			IDFile xRightFile = rightfileHelper.GetIDFile();
			
			// below, if we could find the stream, we'll set this true
			InterfacePtr<IPMStream> 
			iRightPreviewDataFileStream(StreamUtil::CreateFileStreamReadLazy(xRightFile));
			// If nil, we couldn't have opened this
			if (iRightPreviewDataFileStream == nil)
			{
				////cout << "iDataFileStream is nil" << endl;  
				break;
			}
			
			iRightPreviewDataFileStream->Close();
			
			InterfacePtr<ISysFileData> 
			iRightPreviewSysFileData(iRightPreviewWidgetView, IID_ISYSFILEDATA);
			ASSERT(iRightPreviewSysFileData);
			if(!iRightPreviewSysFileData)
			{
				//cout << "iSysFileData is nil" << endl;  
				break;
			}
			iRightPreviewSysFileData->Set(xRightFile);
			
			iRightPreviewWidgetView->Invalidate();
		}

	} while(kFalse);
}

/********************************************************************************************************************
 *****Function: refreshTreeView
 *****Creator:  Toan Nguyen
 *****IN: int action
 *****out: 
 *****Objective: refresh tree view
 ********************************************************************************************************************/
void AMPIssuesDlgObserver::refreshTreeView()
{
	do
	{
		//g_pageNumberCheckOut = "";
		//g_IssueNumberCheckOut = "";
		InterfacePtr<IPanelControlData> panelData(this, UseDefaultIID());	
		// Don't assert, fail silently, the tree view panel may be closed.
		if(panelData == nil)
		{
			break;
		}

		IControlView* treeWidget = panelData->FindWidget(kAMPIssuesTreeViewWidgetID);
		ASSERT(treeWidget);
		if(treeWidget == nil)
		{
			break;
		}
		
		// If this node doesn't have any children, don't show expander Widget
		InterfacePtr<AMPluginDataModel> model(treeWidget, UseDefaultIID());
		ASSERT(model);
		if(!model) {
			break;
		}
		
		PMString RootPath("Browse Issues");
		InterfacePtr<ITreeViewMgr> treeMgr(treeWidget, UseDefaultIID());
		
		model->Rebuild(RootPath);
		treeMgr->ClearTree();
		treeMgr->ChangeRoot(kFalse);
		//treeWidget->Invalidate();
		
	} while(kFalse);
}

/*
void *AMPIssuesDlgObserver::WaitCallback(void *pParam)
{	
	//this = pParam;
	AMPIssuesDlgObserver *IssuesObserver = (AMPIssuesDlgObserver*) pParam;
	//cout << "Please wait to checkin data to CMS..." << IssuesObserver << endl;
	while(!FALSE)
	{
		if (b_SystemWait == TRUE)
		{
			b_SystemWait = FALSE;
			IssuesObserver->realtimeUpdate();
		}
		usleep(100);
	}
	//cout << "finsh to checkin data to CMS..." << endl;
	return NULL;
}
*/

/********************************************************************************************************************
 *****Function: realtimeUpdate
 *****Creator:  Toan Nguyen
 *****IN: int action
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
void AMPIssuesDlgObserver::realtimeUpdate()
{
	do
	{
		//cout << "ReFreshTreeView() " << this << endl;
		InterfacePtr<IPanelControlData> panelData(this, UseDefaultIID());	
		// Don't assert, fail silently, the tree view panel may be closed.
		if(panelData == nil)
		{
			//cout << "Exit here 1" << endl;
			break;
		}
		//cout << "ReFreshTreeView() 2 " << this << endl;
		IControlView* treeWidget = panelData->FindWidget(kAMPIssuesTreeViewWidgetID);
		ASSERT(treeWidget);
		if(treeWidget == nil)
		{
			//cout << "Exit here 2 " << endl;
			break;
		}
		//cout << "ReFreshTreeView() 3 " << this << endl;
		// If this node doesn't have any children, don't show expander Widget
		InterfacePtr<AMPluginDataModel> model(this, UseDefaultIID());
		ASSERT(model);
		if(!model) {
			//cout << "Exit here 3" << endl;
			break;
		}
		
		PMString RootPath("new Issues");
		model->deleteData(RootPath);
		/*
		InterfacePtr<ITreeViewMgr>	treeViewMgr(this, UseDefaultIID());
		if(treeViewMgr == nil)
		{
			printf("treeViewMgr == nil \n");
			break;
		}
		treeViewMgr->ClearTree();
		treeViewMgr->ChangeRoot(kTrue);
		*/
	} while(kFalse);
}

/********************************************************************************************************************
 *****Function: displayImage
 *****Creator:  Toan Nguyen
 *****IN: int action
 *****out: 
 *****Objective: set display image preview path
 ********************************************************************************************************************/
void AMPIssuesDlgObserver::displayImage(int action) {
	////cout << "action value: " << action;
	do {
		string fullImgPath = g_CurPreviewImaPath;
		string fullName = g_CurPreviewNodeName;
		
		InterfacePtr<IPanelControlData> iPanelControlData(this, UseDefaultIID());	
		// Don't assert, fail silently, the tree view panel may be closed.
		if(iPanelControlData == nil)
		{
			break;
		}
		
		// Get Next and Previous buttons
		IControlView* nextButtonView = 
		iPanelControlData->FindWidget(kPreviewImageNextWidgetID);
		ASSERT(nextButtonView);
		if(!nextButtonView) {
			break;
		}
		
		IControlView* prevButtonView = 
		iPanelControlData->FindWidget(kPreviewImagePreviousWidgetID);
		ASSERT(prevButtonView);
		if(!prevButtonView) {
			break;
		}
		
		IControlView* textMessageWidget = iPanelControlData->FindWidget(kAMPIssuesTextMessageWidgetID);
		ASSERT(textMessageWidget);
		if(!textMessageWidget)
		{
			break;
		}
		
		InterfacePtr<ITextControlData> 
		textControlData(textMessageWidget, UseDefaultIID());
		ASSERT(textControlData);
		if(!textControlData)
		{
			break;
		}
				
		
		if (action == NEXT_BTN_SIG) {
			g_CurPreviewImgPos++;
			
			// remove paths
			for (int i = 0; i < g_CurPreviewImgPos; i++) {
				fullImgPath = fullImgPath.substr(fullImgPath.find(";") + 1);
				fullName = fullName.substr(fullName.find(",") + 1);
			}
			
			// get the g_CurPreviewImgPos path
			size_t semicolonPos = fullImgPath.find(";");
			string curImgPath = fullImgPath.substr(0, semicolonPos);
			////cout << "display next image: " << curImgPath << endl;
			this->doPreview(curImgPath.c_str());
	
			if (semicolonPos == fullImgPath.length()-1) {
				nextButtonView->Disable(kTrue);
				prevButtonView->Enable(kTrue, kTrue);
				
			}
			else {
				nextButtonView->Enable(kTrue, kTrue);
				prevButtonView->Enable(kTrue, kTrue);
			}
			
			size_t commaPos = fullName.find(",");
			size_t spacePos = fullName.find(" ");
			string curPageName = "";
			if (commaPos != string::npos) {
				curPageName = fullName.substr(0, commaPos);
				//textControlData->SetString(curPageName.c_str());
			}
			else {
				//textControlData->SetString(fullName.c_str());
				curPageName = fullName;
			}
			
			if (spacePos == 0) {
				curPageName.erase(0, 1);
			}
			textControlData->SetString(curPageName.c_str());
		}
		else if (action == PREV_BTN_SIG) {
			g_CurPreviewImgPos--;
			// remove paths
			for (int i = 0; i < g_CurPreviewImgPos; i++) {
				fullImgPath = fullImgPath.substr(fullImgPath.find(";") + 1);
				fullName = fullName.substr(fullName.find(",") + 1);
			}

			// get the g_CurPreviewImgPos path
			string curImgPath = fullImgPath.substr(0, fullImgPath.find(";"));
			////cout << "display previous image: " << curImgPath << endl;
			this->doPreview(curImgPath.c_str());
			if (g_CurPreviewImgPos == 0) {
				nextButtonView->Enable(kTrue, kTrue);
				prevButtonView->Disable(kTrue);
			}
			else {
				nextButtonView->Enable(kTrue, kTrue);
				prevButtonView->Enable(kTrue, kTrue);
			}
			
			size_t commaPos = fullName.find(",");
			size_t spacePos = fullName.find(" ");
			string curPageName = "";
			if (commaPos != string::npos) {
				curPageName = fullName.substr(0, commaPos);
				//textControlData->SetString(curPageName.c_str());
			}
			else {
				//textControlData->SetString(fullName.c_str());
				curPageName = fullName;
			}
			
			if (spacePos == 0) {
				curPageName.erase(0, 1);
			}
			textControlData->SetString(curPageName.c_str());
		}
		
	} while(kFalse);
	
}

/********************************************************************************************************************
 *****Function: handleDialogCheck
 *****Creator:  Toan Nguyen
 *****IN: PMString CurrentPath, PMString imagePath, int DataType, string pNodename
 *****out: string
 *****Objective: set check box and display preview path
********************************************************************************************************************/
string AMPIssuesDlgObserver::handleDialogCheck(PMString CurrentPath, PMString imagePath, int DataType, string pNodename)
{
	do {
		
		int rsrcID = 0;
		string pageSelected = "";
		string g_IssueNumberCheckOut;
		string tmpIssue_id;
		string PreviewText = "Preview";
		int ChosenNodeCheck = NODE_UNSELECTED;
		if(iconViewtmpChose==nil)
			break;
		
		InterfacePtr<AMPluginDataModel> model(this, UseDefaultIID());
		ASSERT(model);
		if(CurrentPath == model->GetRootPath())
		{
			break;
		}
		
		g_IssueNumberCheckOut = CurrentPath.GrabCString();
		tmpIssue_id = g_IssueNumberCheckOut.substr(g_IssueNumberCheckOut.find_first_of("/") + 1);
		tmpIssue_id = tmpIssue_id.erase(tmpIssue_id.find_first_of("/"), tmpIssue_id.length());
		if((g_Issueid != "") && (tmpIssue_id != g_Issueid))
		{
			AMPCAlert::ModalAlert
			(
			 PMString("\n\nPlease check-in or discard open files before you check-out from new issue."),		// Alert string
			 "OK",							// YES second button
			 kNullString,					// kNoString
			 kNullString, 					// No third button
			 kNoNeedToWaitForDialog,		// Set OK button to default
			 1								// No icon.
			 );
			break;
		}	
		
		if (DataType == PAGE_NODE) {
			//+++++++++++++++++++++++++++++++++++++++++//
			// change param to excuse this progress    //
			string n_page_dispay = g_pageNumberCheckOut;
			string n_name_display = g_CurPreviewNodeName;
			string n_path_display = g_CurPreviewImaPath;
			//+++++++++++++++++++++++++++++++++++++++++//
			RsrcID _currentcheckbox = iconViewtmpChose->GetRsrcID();
			if(_currentcheckbox == kAMPCheckboxOffRsrcID) {
				ChosenNodeCheck = NODE_SELECTED;
				rsrcID = kAMPCheckboxOnRsrcID;
			}else {
				ChosenNodeCheck = NODE_UNSELECTED;
				rsrcID = kAMPCheckboxOffRsrcID;
			}
			
			model->SetCurrentSelected(CurrentPath, ChosenNodeCheck);
			string IssueSelected;
			model->GetParamNodeSelected(CurrentPath, &pageSelected, &IssueSelected);
			
			iconViewtmpChose->SetRsrcPluginID(kAMPPluginID);
			iconViewtmpChose->SetRsrcID(rsrcID);
			iconViewtmpChose = nil;
			
			g_Issueid = tmpIssue_id;
			string pageNeedSelect = " "+pageSelected+",";
			string imagePathSelect = imagePath.GrabCString();
			if(imagePathSelect.find(".jpg") == string::npos)
			{
				//imagePathSelect += ".page" + pageSelected + ";";
				imagePathSelect += pNodename + ";";
			}else
			{
				imagePathSelect += ";";
			}
			
			if(ChosenNodeCheck == NODE_UNSELECTED)
			{
				// remove page number
				if (n_page_dispay.find(pageNeedSelect) != string::npos) {
					n_page_dispay.replace(n_page_dispay.find(pageNeedSelect), pageNeedSelect.length(), ""); // replace "/" by ":"
				}
				
				if (n_name_display.find(pNodename + ",") != string::npos) {
					n_name_display.replace(n_name_display.find(pNodename+","), pNodename.length()+1, ""); // replace "/" by ":"
				}
				
				// remove page path of node unselected
				if (n_path_display.find(imagePathSelect) != string::npos) {
					n_path_display.replace(n_path_display.find(imagePathSelect), imagePathSelect.length(), ""); // replace "/" by ":"
				}
				
				if(n_page_dispay == "") {
					g_Issueid = "";
					g_pageNumberCheckOut = "";
					g_CurPreviewNodeName = "";
					g_CurPreviewImaPath = "";
					string SetDefaultPath =  g_ImagePreview;
					this->doPreview(SetDefaultPath.c_str());
					return "Preview";
					
				}else if(n_path_display.find(";") != string::npos)
				{
					PreviewText = n_name_display.substr(0,n_name_display.find(","));
					// preview image previous of list image selected
					string previewPath = n_path_display.substr(0, n_path_display.find(";"));
					//pageSelected = n_name_display.substr(0, n_name_display.find(","));
					//pageSelected = pageSelected.erase(0, 5); //delete "Page " string
					this->doPreview(previewPath.c_str());
				}
			}else if(ChosenNodeCheck == NODE_SELECTED)
			{
				////cout << "NODE_SELECTED" << endl;
				PreviewText = pNodename;
				if(!(n_page_dispay.find(pageNeedSelect) != string::npos))
				{
					n_page_dispay = n_page_dispay + pageNeedSelect;
					// n_name_display = "Preview Page 1, Preview Page 2, Preview Page 3, "
					n_name_display = n_name_display + PreviewText + ",";
					// n_path_display = "path1; path2; path3; "
					n_path_display = n_path_display + imagePathSelect;
				}
				this->doPreview(imagePath);
				
			}
			AMPUtils::HandleQuickSortString(n_name_display, n_path_display, n_page_dispay);
		}
		
		return PreviewText;
	}while (kFalse);
	
	return "";
}

/********************************************************************************************************************
 *****Function: handleInitIssue
 *****Creator:  Toan Nguyen
 *****IN: 
 *****out: 
 *****Objective: init dialog browse issue list
 ********************************************************************************************************************/
void AMPIssuesDlgObserver::handleInitIssue()
{
	do {
		
		string SetDefaultPath;
		// get checkout button
		InterfacePtr<IWidgetParent> iWidgetParent(this, UseDefaultIID());
		ASSERT(iWidgetParent);
		if(!iWidgetParent)
		{
			break;
		}
		InterfacePtr<IPanelControlData>	iPanelControlData( 
														  (IPanelControlData*)iWidgetParent->QueryParentFor(IID_IPANELCONTROLDATA) );
		
		ASSERT(iPanelControlData);
		if(!iPanelControlData)
		{
			break;
		}
		
		IControlView* iWidgetView = 
		iPanelControlData->FindWidget(kAMPCheckOutButtonWidgetID);
		ASSERT(iWidgetView);
		if(!iWidgetView) {
			break;
		}
		
		// Get Next and Previous buttons
		IControlView* nextButtonView = 
		iPanelControlData->FindWidget(kPreviewImageNextWidgetID);
		ASSERT(nextButtonView);
		if(!nextButtonView) {
			break;
		}
		
		IControlView* prevButtonView = 
		iPanelControlData->FindWidget(kPreviewImagePreviousWidgetID);
		ASSERT(prevButtonView);
		if(!prevButtonView) {
			break;
		}
		IControlView* radioButtonPanel = iPanelControlData->FindWidget(kAMPClusterPanelWidgetID);
		ASSERT(radioButtonPanel);
		if(!radioButtonPanel)
		{
			break;
		}
		
		IControlView* textMessageWidget = iPanelControlData->FindWidget(kAMPIssuesTextMessageWidgetID);
		ASSERT(textMessageWidget);
		if(!textMessageWidget)
		{
			break;
		}
		
		InterfacePtr<ITextControlData> 
		textControlData(textMessageWidget, UseDefaultIID());
		ASSERT(textControlData);
		if(!textControlData)
		{
			break;
		}
		g_CurPreviewImgPos = 0;
		string displayString = g_CurPreviewNodeName.substr(0, g_CurPreviewNodeName.find(",")+1);
		string tmpNodeName = g_CurPreviewNodeName.substr(g_CurPreviewNodeName.find(",") + 1);
		if((displayString == g_CurPreviewNodeName) && (g_CurPreviewNodeName !=""))	// only select one page
		{
			iWidgetView->Enable(kTrue, kTrue);
			nextButtonView->Disable(kTrue);
			prevButtonView->Disable(kTrue);
			radioButtonPanel->Enable(kTrue, kTrue);
			SetDefaultPath = g_CurPreviewImaPath.substr(0, g_CurPreviewImaPath.length()-1);
			displayString = displayString.erase(displayString.length()-1,displayString.length());
			
		}else if(tmpNodeName.length() > 0)	// selected page at first node name
		{
			iWidgetView->Enable(kTrue, kTrue);
			nextButtonView->Enable(kTrue, kTrue);
			prevButtonView->Disable(kTrue);
			radioButtonPanel->Enable(kTrue, kTrue);
			displayString = displayString.erase(displayString.length()-1,displayString.length());
			SetDefaultPath = g_CurPreviewImaPath.substr(0, g_CurPreviewImaPath.find(";"));
		}else
		{
			iWidgetView->Disable(kTrue);
			nextButtonView->Disable(kTrue);
			prevButtonView->Disable(kTrue);
			radioButtonPanel->Disable(kTrue);
			displayString = "Preview";
			g_Resolution = "low";
			SetDefaultPath =  g_ImagePreview;
		}
		////cout << "SetDefaultPath:" << SetDefaultPath << endl;
		textControlData->SetString(displayString.c_str());
		this->doPreview(SetDefaultPath.c_str());
		// Set high or low radio
		InterfacePtr<IPanelControlData> panelControl(iWidgetParent->GetParent(),UseDefaultIID());
		if(!panelControl)
		{
			break;
		}
		IControlView* clusterView = panelControl->FindWidget(kAMPClusterPanelWidgetID);
		if (!clusterView)
		{
			break;
		}
		InterfacePtr<IPanelControlData> clusterPanel(clusterView, UseDefaultIID());
		if (!clusterPanel)
		{
			break;
		}
		
		if(g_Resolution == "high")
		{
			IControlView* HighchildView = clusterPanel->FindWidget(kBscRadioHighResWidgetID);
			if (HighchildView == nil)
			{
				break;
			}
			InterfacePtr<ITriStateControlData> hightriData(HighchildView, UseDefaultIID());
			if (hightriData)
			{
				hightriData->SetState(ITriStateControlData::kSelected, nil, nil);
			}
			
			IControlView* LowchildView = clusterPanel->FindWidget(kBscRadioLowResWidgetID);
			if (LowchildView == nil)
			{
				break;
			}
			InterfacePtr<ITriStateControlData> LowtriData(LowchildView, UseDefaultIID());
			if (LowtriData)
			{
				LowtriData->SetState(ITriStateControlData::kUnselected, nil, nil);
			}
		}else
		{
			IControlView* HighchildView = clusterPanel->FindWidget(kBscRadioHighResWidgetID);
			if (HighchildView == nil)
			{
				break;
			}
			InterfacePtr<ITriStateControlData> hightriData(HighchildView, UseDefaultIID());
			if (hightriData)
			{
				hightriData->SetState(ITriStateControlData::kUnselected, nil, nil);
			}
			
			IControlView* LowchildView = clusterPanel->FindWidget(kBscRadioLowResWidgetID);
			if (LowchildView == nil)
			{
				break;
			}
			InterfacePtr<ITriStateControlData> LowtriData(LowchildView, UseDefaultIID());
			if (LowtriData)
			{
				LowtriData->SetState(ITriStateControlData::kSelected, nil, nil);
			}
		}
		////cout << "handleInitIssue" << endl;
	}while(kFalse);
}

/********************************************************************************************************************
 *****Function: getIssueListContent
 *****Creator:  Toan Nguyen
 *****IN: 
 *****out: 
 *****Objective: get content of browse issue list
 ********************************************************************************************************************/
void AMPIssuesDlgObserver::getIssueListContent()
{
	RangeProgressBar * RefreshProg;
	RefreshProg = new RangeProgressBar("Please wait...", 0, 200, kTrue, kFalse, nil, kFalse);
	string api_prefix = API_PREFIX;
	RefreshProg->SetPosition(5);
	string content = HTTPRequestHelper::getDataFromURL(g_Domain + "/" + api_prefix+"/magazines");
	RefreshProg->SetPosition(55);
	int fraction = 120;
	if(g_Magazine_Count > 0) {
		fraction = fraction / g_Magazine_Count;
	}
	JSONHelper::initMagazines(content);
	for (int i = 0; i < g_Magazine_Count; i++) {
		string issueURL = g_Domain + "/" + api_prefix + "/magazines/" + g_Magazines[i]._id;
		string issueContent = HTTPRequestHelper::getDataFromURL(issueURL);
		JSONHelper::fillMagazine(i, issueContent, FALSE, 60 + i*fraction, 60 + (i+1)*fraction, RefreshProg, TRUE);
	}
	for (int j = 0; j < g_Magazine_Count; j++) {
		if (g_Magazines[j]._issueSize > 0) {
			refreshTreeView();
			RefreshProg->SetPosition(180+j);
			break;
		}
	}
	RefreshProg->~RangeProgressBar();
}

// End, AMPIssuesDlgObserver.cpp.




